home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / xevious.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  8KB  |  378 lines

  1. /***************************************************************************
  2.  
  3.   machine.c
  4.  
  5.   Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
  6.   I/O ports)
  7.  
  8. ***************************************************************************/
  9.  
  10. #include "driver.h"
  11. #include "vidhrdw/generic.h"
  12. #include "cpu/z80/z80.h"
  13.  
  14. unsigned char *xevious_sharedram;
  15. static unsigned char interrupt_enable_1,interrupt_enable_2,interrupt_enable_3;
  16.  
  17. static unsigned char *rom2a;
  18. static unsigned char *rom2b;
  19. static unsigned char *rom2c;
  20. static int xevious_bs[2];
  21.  
  22. static void *nmi_timer;
  23.  
  24. WRITE_HANDLER( xevious_halt_w );
  25.  
  26. /* namco stick number array */
  27. /*
  28.   Input bitmap
  29.     bit0 = UP     KEY
  30.     bit1 = RIGHT KEY
  31.     bit2 = DOWN  KEY
  32.     bit3 = LEFT  KEY
  33.  
  34.   Output direction
  35.           0
  36.         7    1
  37.       6   8   2
  38.         5    3
  39.           4
  40.  */
  41. unsigned char namco_key[16] =
  42. /*  LDRU,LDR,LDU,LD ,LRU,LR ,LU , L ,DRU,DR ,DU , D ,RU , R , U ,NON  */
  43.   {   5 , 5 , 5 , 5 , 7 , 6 , 7 , 6 , 3 , 3 , 4 , 4 , 1 , 2 , 0 , 8 };
  44.  
  45. void xevious_init_machine(void)
  46. {
  47.     rom2a = memory_region(REGION_GFX4);
  48.     rom2b = memory_region(REGION_GFX4)+0x1000;
  49.     rom2c = memory_region(REGION_GFX4)+0x3000;
  50.  
  51.     nmi_timer = 0;
  52.  
  53.     xevious_halt_w (0, 0);
  54. }
  55.  
  56. /* emulation for schematic 9B */
  57. WRITE_HANDLER( xevious_bs_w )
  58. {
  59.     xevious_bs[offset & 0x01] = data;
  60. }
  61.  
  62. READ_HANDLER( xevious_bb_r )
  63. {
  64.     int adr_2b,adr_2c;
  65.     int dat1,dat2;
  66.  
  67.  
  68.     /* get BS to 12 bit data from 2A,2B */
  69.     adr_2b = ((xevious_bs[1]&0x7e)<<6)|((xevious_bs[0]&0xfe)>>1);
  70.     if( adr_2b & 1 ){
  71.         /* high bits select */
  72.         dat1 = ((rom2a[adr_2b>>1]&0xf0)<<4)|rom2b[adr_2b];
  73.     }else{
  74.         /* low bits select */
  75.         dat1 = ((rom2a[adr_2b>>1]&0x0f)<<8)|rom2b[adr_2b];
  76.     }
  77.     adr_2c = (dat1 & 0x1ff)<<2;
  78.     if( offset & 0x01 )
  79.         adr_2c += (1<<11);    /* signal 4H to A11 */
  80.     if( (xevious_bs[0]&1) ^ ((dat1>>10)&1) )
  81.         adr_2c |= 1;
  82.     if( (xevious_bs[1]&1) ^ ((dat1>>9)&1) )
  83.         adr_2c |= 2;
  84.     if( offset & 0x01 ){
  85.         /* return BB1 */
  86.         dat2 = rom2c[adr_2c];
  87.     }else{
  88.         /* return BB0 */
  89.         dat2 =rom2c[adr_2c];
  90.         /* swap bit 6 & 7 */
  91.         dat2 = (dat2 & 0x3f) | ((dat2 & 0x80) >> 1) | ((dat2 & 0x40) << 1);
  92.         /* flip x & y */
  93.         dat2 ^= (dat1 >> 4) & 0x40;
  94.         dat2 ^= (dat1 >> 2) & 0x80;
  95.     }
  96.     return dat2;
  97. }
  98.  
  99. READ_HANDLER( xevious_sharedram_r )
  100. {
  101.     return xevious_sharedram[offset];
  102. }
  103.  
  104. WRITE_HANDLER( xevious_sharedram_w )
  105. {
  106.     xevious_sharedram[offset] = data;
  107. }
  108.  
  109.  
  110.  
  111. READ_HANDLER( xevious_dsw_r )
  112. {
  113.     int bit0,bit1;
  114.  
  115.     bit0 = (input_port_0_r(0) >> offset) & 1;
  116.     bit1 = (input_port_1_r(0) >> offset) & 1;
  117.  
  118.     return bit0 | (bit1 << 1);
  119. }
  120.  
  121. /***************************************************************************
  122.  
  123.  Emulate the custom IO chip.
  124.  
  125. ***************************************************************************/
  126. static int customio_command;
  127. static int mode,credits;
  128. static int auxcoinpercred,auxcredpercoin;
  129. static int leftcoinpercred,leftcredpercoin;
  130. static int rightcoinpercred,rightcredpercoin;
  131. static unsigned char customio[16];
  132.  
  133.  
  134. WRITE_HANDLER( xevious_customio_data_w )
  135. {
  136.     customio[offset] = data;
  137.  
  138. logerror("%04x: custom IO offset %02x data %02x\n",cpu_get_pc(),offset,data);
  139.  
  140.     switch (customio_command)
  141.     {
  142.         case 0xa1:
  143.             if (offset == 0)
  144.             {
  145.                 if (data == 0x05)
  146.                     mode = 1;    /* go into switch mode */
  147.                 else    /* go into credit mode */
  148.                 {
  149.                     credits = 0;    /* this is a good time to reset the credits counter */
  150.                     mode = 0;
  151.                 }
  152.             }
  153.             else if (offset == 7)
  154.             {
  155.                 auxcoinpercred = customio[1];
  156.                 auxcredpercoin = customio[2];
  157.                 leftcoinpercred = customio[3];
  158.                 leftcredpercoin = customio[4];
  159.                 rightcoinpercred = customio[5];
  160.                 rightcredpercoin = customio[6];
  161.             }
  162.             break;
  163.  
  164.         case 0x68:
  165.             if (offset == 6)
  166.             {
  167.                 /* it is not known how the parameters control the explosion. */
  168.                 /* We just use samples. */
  169.                 if (memcmp(customio,"\x40\x40\x40\x01\xff\x00\x20",7) == 0)
  170.                     sample_start (0, 0, 0);
  171.                 else if (memcmp(customio,"\x30\x40\x00\x02\xdf\x00\x10",7) == 0)
  172.                     sample_start (0, 1, 0);
  173.             }
  174.             break;
  175.     }
  176. }
  177.  
  178.  
  179. READ_HANDLER( xevious_customio_data_r )
  180. {
  181.     if (customio_command != 0x71)
  182.         logerror("%04x: custom IO read offset %02x\n",cpu_get_pc(),offset);
  183.  
  184.     switch (customio_command)
  185.     {
  186.         case 0x71:    /* read input */
  187.         case 0xb1:    /* only issued after 0xe1 (go into credit mode) */
  188.             if (offset == 0)
  189.             {
  190.                 if (mode)    /* switch mode */
  191.                 {
  192.                     /* bit 7 is the service switch */
  193.                     return readinputport(4);
  194.                 }
  195.                 else    /* credits mode: return number of credits in BCD format */
  196.                 {
  197.                     int in;
  198.                     static int leftcoininserted;
  199.                     static int rightcoininserted;
  200.                     static int auxcoininserted;
  201.  
  202.  
  203.                     in = readinputport(4);
  204.  
  205.                     /* check if the user inserted a coin */
  206.                     if (leftcoinpercred > 0)
  207.                     {
  208.                         if ((in & 0x10) == 0 && credits < 99)
  209.                         {
  210.                             leftcoininserted++;
  211.                             if (leftcoininserted >= leftcoinpercred)
  212.                             {
  213.                                 credits += leftcredpercoin;
  214.                                 leftcoininserted = 0;
  215.                             }
  216.                         }
  217.                         if ((in & 0x20) == 0 && credits < 99)
  218.                         {
  219.                             rightcoininserted++;
  220.                             if (rightcoininserted >= rightcoinpercred)
  221.                             {
  222.                                 credits += rightcredpercoin;
  223.                                 rightcoininserted = 0;
  224.                             }
  225.                         }
  226.                         if ((in & 0x40) == 0 && credits < 99)
  227.                         {
  228.                             auxcoininserted++;
  229.                             if (auxcoininserted >= auxcoinpercred)
  230.                             {
  231.                                 credits += auxcredpercoin;
  232.                                 auxcoininserted = 0;
  233.                             }
  234.                         }
  235.                     }
  236.                     else credits = 2;
  237.  
  238.  
  239.                     /* check for 1 player start button */
  240.                     if ((in & 0x04) == 0)
  241.                         if (credits >= 1) credits--;
  242.  
  243.                     /* check for 2 players start button */
  244.                     if ((in & 0x08) == 0)
  245.                         if (credits >= 2) credits -= 2;
  246.  
  247.                     return (credits / 10) * 16 + credits % 10;
  248.                 }
  249.             }
  250.             else if (offset == 1)
  251.             {
  252.                 int in;
  253.  
  254.  
  255.                 in = readinputport(2);    /* player 1 input */
  256.                 if (mode == 0)    /* convert joystick input only when in credits mode */
  257.                     in = namco_key[in & 0x0f] | (in & 0xf0);
  258.                 return in;
  259.             }
  260.             else if (offset == 2)
  261.             {
  262.                 int in;
  263.  
  264.  
  265.                 in = readinputport(3);    /* player 2 input */
  266.                 if (mode == 0)    /* convert joystick input only when in credits mode */
  267.                     in = namco_key[in & 0x0f] | (in & 0xf0);
  268.                 return in;
  269.             }
  270.  
  271.             break;
  272.  
  273.         case 0x74:        /* protect data read ? */
  274.             if (offset == 3)
  275.             {
  276.                 if (customio[0] == 0x80 || customio[0] == 0x10)
  277.                     return 0x05;    /* 1st check */
  278.                 else
  279.                     return 0x95;  /* 2nd check */
  280.             }
  281.             else return 0x00;
  282.             break;
  283.     }
  284.  
  285.     return -1;
  286. }
  287.  
  288.  
  289. READ_HANDLER( xevious_customio_r )
  290. {
  291.     return customio_command;
  292. }
  293.  
  294. void xevious_nmi_generate (int param)
  295. {
  296.     cpu_cause_interrupt (0, Z80_NMI_INT);
  297. }
  298.  
  299.  
  300. WRITE_HANDLER( xevious_customio_w )
  301. {
  302.     if (data != 0x10 && data != 0x71)
  303.         logerror("%04x: custom IO command %02x\n",cpu_get_pc(),data);
  304.  
  305.     customio_command = data;
  306.  
  307.     switch (data)
  308.     {
  309.         case 0x10:
  310.             if (nmi_timer) timer_remove (nmi_timer);
  311.             nmi_timer = 0;
  312.             return; /* nop */
  313.     }
  314.  
  315.     nmi_timer = timer_pulse (TIME_IN_USEC (50), 0, xevious_nmi_generate);
  316. }
  317.  
  318.  
  319.  
  320. WRITE_HANDLER( xevious_halt_w )
  321. {
  322.     if (data & 1)
  323.     {
  324.         cpu_set_reset_line(1,CLEAR_LINE);
  325.         cpu_set_reset_line(2,CLEAR_LINE);
  326.     }
  327.     else
  328.     {
  329.         cpu_set_reset_line(1,ASSERT_LINE);
  330.         cpu_set_reset_line(2,ASSERT_LINE);
  331.     }
  332. }
  333.  
  334.  
  335.  
  336. WRITE_HANDLER( xevious_interrupt_enable_1_w )
  337. {
  338.     interrupt_enable_1 = (data&1);
  339. }
  340.  
  341.  
  342.  
  343. int xevious_interrupt_1(void)
  344. {
  345.     if (interrupt_enable_1) return interrupt();
  346.     else return ignore_interrupt();
  347. }
  348.  
  349.  
  350.  
  351. WRITE_HANDLER( xevious_interrupt_enable_2_w )
  352. {
  353.     interrupt_enable_2 = data & 1;
  354. }
  355.  
  356.  
  357.  
  358. int xevious_interrupt_2(void)
  359. {
  360.     if (interrupt_enable_2) return interrupt();
  361.     else return ignore_interrupt();
  362. }
  363.  
  364.  
  365.  
  366. WRITE_HANDLER( xevious_interrupt_enable_3_w )
  367. {
  368.     interrupt_enable_3 = !(data & 1);
  369. }
  370.  
  371.  
  372.  
  373. int xevious_interrupt_3(void)
  374. {
  375.     if (interrupt_enable_3) return nmi_interrupt();
  376.     else return ignore_interrupt();
  377. }
  378.